const { Connection, Keypair, LAMPORTS_PER_SOL, PublicKey, Transaction, SystemProgram, sendAndConfirmTransaction } = require('@solana/web3.js');
const { 
  getAssociatedTokenAddress, 
  createAssociatedTokenAccountInstruction, 
  createTransferInstruction,
  getAccount
} = require('@solana/spl-token');
const fs = require('fs');
const path = require('path');

// 配置
const DEVNET_RPC = 'https://api.devnet.solana.com';
const AIRDROP_AMOUNT = 2; // SOL数量 (减少到2避免限制)
const NUM_ADDRESSES = 5; // 减少数量避免限制
const TOKEN_MINT = '4C5SJj6Gfd86jTS7PgtYmjGjGxrG9GAuLUmQ47vGnQPc'; // 您的代币地址
const CREATOR_ADDRESS = 'shTdKtBScJMC4GkKmasiE9iMKrtZnMFUtwVTdSXsKac'; // 您的地址

// 加载现有地址或创建新的
async function loadOrCreateTestAddresses() {
  const addressesPath = path.join(__dirname, 'test-addresses.json');
  
  if (fs.existsSync(addressesPath)) {
    console.log('📁 找到现有测试地址文件，正在加载...');
    try {
      const existingAddresses = JSON.parse(fs.readFileSync(addressesPath, 'utf8'));
      console.log(`✅ 加载了 ${existingAddresses.length} 个现有地址`);
      
      // 检查现有地址的余额
      const connection = new Connection(DEVNET_RPC, 'confirmed');
      const validAddresses = [];
      
      for (const addr of existingAddresses) {
        try {
          const publicKey = new PublicKey(addr.publicKey);
          const balance = await connection.getBalance(publicKey);
          const solBalance = balance / LAMPORTS_PER_SOL;
          
          if (solBalance > 0.01) { // 至少有0.01 SOL
            addr.balance = solBalance;
            validAddresses.push(addr);
            console.log(`✅ ${addr.publicKey}: ${solBalance.toFixed(6)} SOL`);
          } else {
            console.log(`⚠️ ${addr.publicKey}: 余额不足 (${solBalance.toFixed(6)} SOL)`);
          }
        } catch (error) {
          console.log(`❌ 检查地址 ${addr.publicKey} 失败: ${error.message}`);
        }
      }
      
      if (validAddresses.length >= 2) {
        console.log(`\n🎯 找到 ${validAddresses.length} 个可用地址，跳过生成新地址`);
        return validAddresses;
      } else {
        console.log(`\n⚠️ 只有 ${validAddresses.length} 个可用地址，需要生成更多`);
      }
    } catch (error) {
      console.log('❌ 加载现有地址失败:', error.message);
    }
  }
  
  return await generateTestAddresses();
}

async function generateTestAddresses() {
  console.log('🚀 开始生成测试地址...\n');
  
  const connection = new Connection(DEVNET_RPC, 'confirmed');
  const addresses = [];
  
  for (let i = 0; i < NUM_ADDRESSES; i++) {
    try {
      // 生成新的密钥对
      const keypair = Keypair.generate();
      const publicKey = keypair.publicKey.toString();
      const secretKey = Array.from(keypair.secretKey);
      
      console.log(`📍 地址 ${i + 1}: ${publicKey}`);
      
      // 尝试空投SOL
      console.log(`💰 正在空投 ${AIRDROP_AMOUNT} SOL...`);
      
      try {
        const airdropSignature = await connection.requestAirdrop(
          keypair.publicKey,
          AIRDROP_AMOUNT * LAMPORTS_PER_SOL
        );
        
        // 等待确认
        await connection.confirmTransaction(airdropSignature);
        
        // 检查余额
        const balance = await connection.getBalance(keypair.publicKey);
        const solBalance = balance / LAMPORTS_PER_SOL;
        
        console.log(`✅ 空投成功！余额: ${solBalance} SOL`);
        
        addresses.push({
          index: i + 1,
          publicKey,
          secretKey,
          balance: solBalance,
          airdropSignature,
          createdAt: new Date().toISOString()
        });
        
      } catch (airdropError) {
        console.log(`❌ 空投失败: ${airdropError.message}`);
        console.log(`ℹ️  可能需要手动从 https://faucet.solana.com 获取SOL`);
        
        addresses.push({
          index: i + 1,
          publicKey,
          secretKey,
          balance: 0,
          airdropError: airdropError.message,
          createdAt: new Date().toISOString()
        });
      }
      
      // 添加延迟避免速率限制
      if (i < NUM_ADDRESSES - 1) {
        console.log('⏳ 等待3秒避免速率限制...');
        await new Promise(resolve => setTimeout(resolve, 3000));
      }
      
    } catch (error) {
      console.error(`❌ 生成地址 ${i + 1} 时出错:`, error.message);
    }
  }

  return addresses;
}

// 转移代币给测试地址
async function distributeTokensToAddresses(addresses) {
  console.log('\n🎯 开始分发代币给测试地址...');
  
  const connection = new Connection(DEVNET_RPC, 'confirmed');
  const tokenMint = new PublicKey(TOKEN_MINT);
  
  // 加载创建者钱包 (从现有的测试钱包文件)
  let creatorKeypair;
  try {
    const creatorWalletPath = path.join(__dirname, '..', 'test-wallet-1754098590485.json');
    if (fs.existsSync(creatorWalletPath)) {
      const walletData = JSON.parse(fs.readFileSync(creatorWalletPath, 'utf8'));
      creatorKeypair = Keypair.fromSecretKey(new Uint8Array(walletData.secretKey));
      console.log(`✅ 加载创建者钱包: ${creatorKeypair.publicKey.toString()}`);
    } else {
      console.log('❌ 未找到创建者钱包文件，无法分发代币');
      return addresses;
    }
  } catch (error) {
    console.log('❌ 加载创建者钱包失败:', error.message);
    return addresses;
  }
  
  // 检查创建者的代币余额
  try {
    const creatorTokenAccount = await getAssociatedTokenAddress(tokenMint, creatorKeypair.publicKey);
    const account = await getAccount(connection, creatorTokenAccount);
    const creatorTokenBalance = Number(account.amount);
    
    console.log(`💎 创建者代币余额: ${creatorTokenBalance / Math.pow(10, 9)} 个代币`);
    
    if (creatorTokenBalance === 0) {
      console.log('❌ 创建者没有代币，无法分发');
      return addresses;
    }
    
    // 为每个有SOL余额的地址分发代币
    const validAddresses = addresses.filter(addr => addr.balance > 0);
    const tokensPerAddress = Math.floor(creatorTokenBalance / validAddresses.length / 10); // 分发10%
    
    console.log(`📊 将向 ${validAddresses.length} 个地址分发代币，每个地址 ${tokensPerAddress / Math.pow(10, 9)} 个代币`);
    
    for (let i = 0; i < validAddresses.length; i++) {
      const addr = validAddresses[i];
      try {
        console.log(`\n💸 向地址 ${i + 1} 分发代币: ${addr.publicKey}`);
        
        const recipientKeypair = Keypair.fromSecretKey(new Uint8Array(addr.secretKey));
        const recipientTokenAccount = await getAssociatedTokenAddress(tokenMint, recipientKeypair.publicKey);
        
        // 检查接收者代币账户是否存在
        let recipientAccountExists = false;
        try {
          await getAccount(connection, recipientTokenAccount);
          recipientAccountExists = true;
          console.log(`💎 接收者代币账户已存在`);
        } catch {
          console.log(`💎 接收者代币账户不存在，将创建`);
        }
        
        const transaction = new Transaction();
        
        // 如果需要，创建接收者代币账户
        if (!recipientAccountExists) {
          transaction.add(
            createAssociatedTokenAccountInstruction(
              creatorKeypair.publicKey, // payer
              recipientTokenAccount,    // ata
              recipientKeypair.publicKey, // owner
              tokenMint                 // mint
            )
          );
        }
        
        // 添加转账指令
        transaction.add(
          createTransferInstruction(
            creatorTokenAccount,      // source
            recipientTokenAccount,    // destination
            creatorKeypair.publicKey, // owner
            BigInt(tokensPerAddress)  // amount
          )
        );
        
        // 发送交易
        const signature = await sendAndConfirmTransaction(
          connection,
          transaction,
          [creatorKeypair],
          { commitment: 'confirmed' }
        );
        
        console.log(`✅ 代币转移成功！交易签名: ${signature}`);
        
        // 更新地址信息
        addr.tokenBalance = tokensPerAddress / Math.pow(10, 9);
        addr.tokenTransferSignature = signature;
        
        // 添加延迟
        if (i < validAddresses.length - 1) {
          console.log('⏳ 等待3秒后继续...');
          await new Promise(resolve => setTimeout(resolve, 3000));
        }
        
      } catch (error) {
        console.log(`❌ 向地址 ${addr.publicKey} 分发代币失败: ${error.message}`);
        addr.tokenTransferError = error.message;
      }
    }
    
  } catch (error) {
    console.log('❌ 检查创建者代币余额失败:', error.message);
  }
  
  return addresses;
}

async function generateTestAddressesWithTokens() {
  console.log('🎯 生成带代币的测试地址');
  console.log('='.repeat(50));
  
  // 1. 加载或生成测试地址
  const addresses = await loadOrCreateTestAddresses();
  
  // 2. 分发代币给有SOL余额的地址
  const updatedAddresses = await distributeTokensToAddresses(addresses);
  
  // 3. 保存更新后的地址
  const outputPath = path.join(__dirname, 'test-addresses.json');
  fs.writeFileSync(outputPath, JSON.stringify(updatedAddresses, null, 2));
  
  console.log('\n📄 测试地址已保存到:', outputPath);
  console.log('\n📊 生成结果摘要:');
  console.log(`- 总地址数: ${updatedAddresses.length}`);
  
  const validAddresses = updatedAddresses.filter(a => a.balance > 0);
  const tokenAddresses = updatedAddresses.filter(a => a.tokenBalance > 0);
  
  console.log(`- 有SOL余额: ${validAddresses.length}`);
  console.log(`- 有代币余额: ${tokenAddresses.length}`);
  
  // 显示可用于测试的地址
  console.log('\n🎯 可用于交易测试的地址:');
  tokenAddresses.forEach((addr, index) => {
    console.log(`${index + 1}. ${addr.publicKey}`);
    console.log(`   SOL余额: ${addr.balance.toFixed(6)} SOL`);
    console.log(`   代币余额: ${addr.tokenBalance.toFixed(2)} 个`);
    if (addr.tokenTransferSignature) {
      console.log(`   转账签名: ${addr.tokenTransferSignature}`);
    }
    console.log('');
  });
  
  // 生成买家钱包文件供真实交易使用
  if (tokenAddresses.length > 0) {
    console.log('\n🔑 生成买家钱包文件...');
    
    const buyerAddress = tokenAddresses[0]; // 使用第一个有代币的地址作为买家
    const buyerWalletData = {
      publicKey: buyerAddress.publicKey,
      secretKey: buyerAddress.secretKey
    };
    
    const buyerWalletPath = path.join(__dirname, '..', '..', 'frontend', 'buyer-wallet.json');
    fs.writeFileSync(buyerWalletPath, JSON.stringify(buyerWalletData, null, 2));
    
    console.log(`✅ 买家钱包已生成: ${buyerWalletPath}`);
    console.log(`📍 买家地址: ${buyerAddress.publicKey}`);
    console.log(`💰 SOL余额: ${buyerAddress.balance.toFixed(6)} SOL`);
    console.log(`🪙 代币余额: ${buyerAddress.tokenBalance.toFixed(2)} 个`);
    
    // 生成卖家钱包文件 (使用第二个地址作为卖家)
    if (tokenAddresses.length > 1) {
      const sellerAddress = tokenAddresses[1];
      const sellerWalletData = {
        publicKey: sellerAddress.publicKey,
        secretKey: sellerAddress.secretKey
      };
      
      const sellerWalletPath = path.join(__dirname, '..', '..', 'frontend', 'seller-wallet.json');
      fs.writeFileSync(sellerWalletPath, JSON.stringify(sellerWalletData, null, 2));
      
      console.log(`✅ 卖家钱包已生成: ${sellerWalletPath}`);
      console.log(`📍 卖家地址: ${sellerAddress.publicKey}`);
      console.log(`💰 SOL余额: ${sellerAddress.balance.toFixed(6)} SOL`);
      console.log(`🪙 代币余额: ${sellerAddress.tokenBalance.toFixed(2)} 个`);
    }
    
    console.log('\n🚀 现在可以运行真实交易测试:');
    console.log('cd ../../frontend && node scripts/real-trade-test.js --confirm');
  }
  
  return updatedAddresses;
}

// 如果直接运行此脚本
if (require.main === module) {
  generateTestAddressesWithTokens()
    .then(() => {
      console.log('\n🎉 完成！');
      process.exit(0);
    })
    .catch(error => {
      console.error('❌ 错误:', error);
      process.exit(1);
    });
}

module.exports = { generateTestAddressesWithTokens, generateTestAddresses };
